function setrangegui(varargin)
% GUI to change the plotting range
% 
% ### Syntax
% 
% `swplot.setrangegui`
%
% `swplot.setrangegui(hFigure)`
%
% `swplot.setrangegui(~,~,hfigure)`
% 
% ### Description
% 
% `swplot.setrangegui` produces a window that enables changing
% the limits of the active swplot figure. After changing the range, every
% object that is created with the `swplot.plot...` commands will be
% replotted using the new `range` parameter.
%  
% `swplot.setrangegui(hFigure)` chow the gui for the swplot figure related
% the `hFigure` handle.
%  
% `swplot.setrangegui(~,~,hfigure)` can be used in figure callbacks, for
% example by assigning it to `'ClickedCallback'` property of a button.
% 
% ### Input Arguments
% 
% `hFigure`
% : Handle of the swplot figure. Default value is the active figure.
%

% take care that it is used as callback or just normally
if nargin==2 || nargin==0
    hFigure  = swplot.activefigure;
elseif nargin==1
    hFigure = varargin{1};
elseif nargin==3
    hFigure = varargin{3};
end

% if there is no crystal, don't do anything
if ~isappdata(hFigure,'obj')
    return
end

% load data from figure
rDat      = getappdata(hFigure,'range');
range     = rDat.range;
unit      = rDat.unit;
parentPos = get(hFigure,'Position');
fWidth    = 195;
fHeight   = 240;

switch unit
    case 'lu'
        tLabel = {'a:' 'b:' 'c:'};
    case 'xyz'
        tLabel = {'x:' 'y:' 'z:'};
end

% Figure number
if verLessThan('matlab','8.4.0')
    figNum = hFigure;
else
    figNum = hFigure.Number;
end

%    'WindowStyle',    'modal',...
objMod = findobj('Tag',['setRange_' num2str(figNum)]);

if ~isempty(objMod)
    close(objMod)
    return
end

objMod = figure(...
    'Units',          'pixel',...
    'Position',       [parentPos(1)+150 parentPos(2)+parentPos(4)-300 fWidth fHeight],...
    'Name',           'Plot range',...
    'NumberTitle',    'off',...
    'DockControls',   'off',...
    'Tag',            ['setRange_' num2str(figNum)],...
    'MenuBar',        'none',...
    'Toolbar',        'none',...
    'Resize',         'off',...
    'Visible',        'on');

handles.objMod = objMod;
handles.panel(1) = uipanel(objMod,...
    'Position',       [0 0 1 1],...
    'BorderType',     'none');
handles.checkbox_ud = uicontrol(handles.panel(1),...
    'Style',           'CheckBox',...
    'Units',           'pixel',...
    'String',          'Live Update',...
    'Enable',          'Off',...
    'Position',        [3 5 80 15]);
handles.text(1) = uicontrol(handles.panel(1),...
    'Style',           'text',...
    'String',          'Atoms in range:',...
    'Units',           'pixel',...
    'Position',        [3 30 80 15]);
handles.text(2) = uicontrol(handles.panel(1),...
    'Style',           'edit',...
    'String',          '30',...
    'Enable',          'off',...
    'Units',           'pixel',...
    'Position',        [110 30 60 15]);
handles.panel(2) = uipanel(objMod,...
    'Units',            'pixel',...
    'Title',            'Full XYZ Range',...
    'Position',         [1 50 fWidth 80]);
handles.panel(3) = uipanel(objMod,...
    'Units',            'pixel',...
    'Title',            'Axial Range Limits',...
    'Position',         [1 131 fWidth 109]);
handles.text(3) = uicontrol(handles.panel(3),...
    'Style',           'text',...
    'String',          tLabel{3},...
    'Units',           'pixel',...
    'Position',        [5 5 20 15]);
handles.text(4) = uicontrol(handles.panel(3),...
    'Style',           'text',...
    'String',          tLabel{2},...
    'Units',           'pixel',...
    'Position',        [5 30 20 15]);
handles.text(5) = uicontrol(handles.panel(3),...
    'Style',           'text',...
    'String',          tLabel{1},...
    'Units',           'pixel',...
    'Position',        [5 55 20 15]);
handles.edit_range(1,1) = uicontrol(handles.panel(3),...
    'Style',     'edit',...
    'BackgroundColor',[1 1 1],...
    'Position',  [30 56 70 20]);
handles.edit_range(1,2) = uicontrol(handles.panel(3),...
    'Style',     'edit',...
    'BackgroundColor',[1 1 1],...
    'Position',  [105 56 70 20]);
handles.edit_range(2,1) = uicontrol(handles.panel(3),...
    'Style',     'edit',...
    'BackgroundColor',[1 1 1],...
    'Position',  [30 31 70 20]);
handles.edit_range(2,2) = uicontrol(handles.panel(3),...
    'Style',     'edit',...
    'BackgroundColor',[1 1 1],...
    'Position',  [105 31 70 20]);
handles.edit_range(3,1) = uicontrol(handles.panel(3),...
    'Style',     'edit',...
    'BackgroundColor',[1 1 1],...
    'Position',  [30 6 70 20]);
handles.edit_range(3,2) = uicontrol(handles.panel(3),...
    'Style',     'edit',...
    'BackgroundColor',[1 1 1],...
    'Position',  [105 6 70 20]);
handles.pushbutton_expand = uicontrol(handles.panel(2),...
    'Style',           'pushbutton',...
    'Units',           'pixel',...
    'String',          'Expand',...
    'Position',        [fWidth/2-40 44 80 20],...
    'Callback',         {@Callback_Scale hFigure objMod 1});
handles.pushbutton_contract = uicontrol(handles.panel(2),...
    'Style',           'pushbutton',...
    'Units',           'pixel',...
    'String',          'Contract',...
    'Position',        [fWidth/2-40 24 80 20],...
    'Callback',         {@Callback_Scale hFigure objMod 0});
handles.pushbutton_singlecell = uicontrol(handles.panel(2),...
    'Style',           'pushbutton',...
    'Units',           'pixel',...
    'String',          'Single Cell',...
    'Position',        [fWidth/2-40 4 80 20],...
    'Callback',         {@Callback_Single objMod});
handles.pushbutton_apply = uicontrol(handles.panel(1),...
    'Style',           'pushbutton',...
    'Units',           'pixel',...
    'String',          'Apply',...
    'Position',        [90 3 50 20],...
    'Callback',        {@Callback_Range hFigure objMod 0});
handles.pushbutton_ok = uicontrol(handles.panel(1),...
    'Style',           'pushbutton',...
    'Units',           'pixel',...
    'String',          'OK',...
    'Position',        [140 3 50 20],...
    'Callback',        {@Callback_Range hFigure objMod 1});

for ii=1:3
    for jj=1:2
        set(handles.edit_range(ii,jj),'String',sprintf('%.3f',range(ii,jj)));
    end
end

handles.text(6) = uicontrol(handles.panel(3),...
    'Style',           'text',...
    'String',          'Minimum',...
    'Units',           'pixel',...
    'Position',        [37 77 50 15]);
handles.text(7) = uicontrol(handles.panel(3),...
    'Style',           'text',...
    'String',          'Maximum',...
    'Units',           'pixel',...
    'Position',        [110 77 50 15]);

setappdata(objMod,'handles',handles);

    function Callback_Range(~, ~, hFigure, objMod , isclose)
        
        param   = getappdata(hFigure,'param');
        rDat    = getappdata(hFigure,'range');
        range   = rDat.range;
        obj     = getappdata(hFigure,'obj');
        handles = getappdata(objMod,'handles');
        
        
        for iii=1:3
            for jjj=1:2
                range(iii,jjj) = str2double(get(handles.edit_range(iii,jjj),'String'));
            end
        end
        
        if all((range(:,1) - range(:,2)) < 0)
            % remove range from parameter list
            rIdx = find(ismember(param(1:2:end),'range'));
            if numel(rIdx) > 0
                param(2*rIdx(1) + [-1 0]) = [];
            end
            
            plot(obj, param{:},'range',range);
            %figure(objMod);
        end
        
        % Okay button closes the settings window
        if isclose
            delete(handles.objMod);
        end
    end

    function Callback_Single(~, ~, objMod)
        
        handles = getappdata(objMod,'handles');
        for iii=1:3
            set(handles.edit_range(iii,1),'String', '0.000');
            set(handles.edit_range(iii,2),'String', '1.000');
        end
    end

    function Callback_Scale(~, ~, hFigure, ~, expand)
        
        obj     = getappdata(hFigure,'obj');
        lattice = obj.lattice;
        abc     = lattice.lat_const;
        d       = 0.1 * min(abc)./abc;
        
        range = zeros(3,2);
        for iii=1:3
            for jjj=1:2
                range(iii,jjj) = str2double(get(handles.edit_range(iii,jjj),'String'));
            end
        end
        
        if ~expand
            d = -d;
        end
        range(:,1) = range(:,1) - d';
        range(:,2) = range(:,2) + d';
        
        
        for iii=1:3
            for jjj=1:2
                set(handles.edit_range(iii,jjj),'String',sprintf('%6.3f',range(iii,jjj)));
            end
        end
        
        
    end
end